# module name model.py
# $Id: model.py 70fe0286d122 2013/07/17 05:39:39 pgurumur $
# Copyright (c) 2013 Prabhu Gurumurthy <pgurumur@gmail.com>
#
# Permission to use, copy, modify, and distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# File model.py generated on Wed, July 10, 2013 15:41:16 PM
#
__version__  = "$Revision: 70fe0286d122 $"
__author__   = "$Author: pgurumur $"
__modified__ = "$Date: 2013-07-17 05:39:39Z $"

import datetime

from sqlalchemy import Column, Integer, DateTime, Unicode, MetaData
from sqlalchemy.exc import IntegrityError, StatementError, InvalidRequestError
from dbmodel import ModelBase, validate, Base, tableList, ModelError

class BaseModel(ModelBase):
   __abstract__ = True

   pk = Column(Integer, primary_key = True, autoincrement = True)
   created = Column(DateTime, nullable = False, default = datetime.datetime.now)
   updated = Column(DateTime, nullable = False)
   comments = Column(Unicode(1000), nullable = True)

   @validate(update = False)
   def __init__(self, *args, **kwargs):
      super(BaseModel, self).__init__()
      self._query = self.q
      self._uquery = self.t.update()
      if len(kwargs):
         for attr, value in kwargs.items():
            fvalue = self.get_col(attr).is_(value)
            self._query = self._query.filter(fvalue)
            self._uquery = self._uquery.where(fvalue)

   @property
   def updated_time(self):
      return self["updated"].strftime("%a, %B %d %Y, %H:%M:%S")

   @validate(update = True)
   def save(self, *args, **kwargs):
      retval = 0
      try:
         self.__session__.add(self)
         self.__session__.commit()
      except IntegrityError as err:
         raise ModelError(err)
      except StatementError as err:
         raise ModelError(err)
      except InvalidRequestError as err:
         raise ModelError(err)
      else:
         retval = self["pk"]

      return retval

   @validate(update = True)
   def update(self, *args, **kwargs):
      try:
         pk = self["pk"]
      except IndexError as err:
         raise ModelError("invalid where clause")

      items = {}
      for attr, value in kwargs.items():
         items[self.get_col(attr)] = value

      items[self.get_col("updated")] = datetime.datetime.now()
      try:
         stmt = self._uquery.values(items)
         stmt.execute()
      except IntegrityError as err:
         raise ModelError(err)
      except StatementError as err:
         raise ModelError(err)
      except InvalidRequestError as err:
         raise ModelError(err)

   @property
   def created_time(self):
      return self["created"].strftime("%a, %B %d %Y, %H:%M:%S")

   def __getitem__(self, key):
      return [ix[0] for ix in self._query.values(self.get_col(key))][0]

   def get(self, *args):
      flag = False
      retval = None
      if len(args):
         flag = True

      if flag:
         cols = []
         for ix in args:
            cols.append(self.get_col(ix))

         retval = [ix for ix in self._query.values(*cols)]

      return retval

def create(Engine, Session):
   try:
      if Engine:
         Base.metadata.create_all(Engine)
      else:
         raise ModelError("no engine defined")
   except OperationalError as err:
      raise ModelError(err)
   except NoReferencedTableError as err:
      raise ModelError(err)
   except CircularDependencyError as err:
      raise ModelError(err)
   else:
      md = MetaData(bind = Engine)
      for key, value in Base.metadata.tables.items():
         value.metadata = md

      for name, cls in tableList.items():
         cls.__session__ = Session
         cls.__engine__ = Engine
